> ## Documentation Index
> Fetch the complete documentation index at: https://edimez14-password_generator.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Profile Management

> Manage user profiles including personal information, avatar uploads, and account deletion

## Overview

The Profile Management system allows authenticated users to view and update their personal information, upload custom avatars, and manage their account settings. All profile operations are secured and restricted to the authenticated user.

## User Profile Model

The user profile is based on Django's `AbstractUser` with custom extensions (`models.py:5-16`):

```python theme={null}
class Users(AbstractUser):
    email = models.EmailField(max_length=200, unique=True)
    first_name = models.CharField(max_length=200, blank=True, default='')
    last_name = models.CharField(max_length=200, blank=True, default='')
    number_phone = models.CharField(max_length=10, blank=True, null=True)
    avatar = models.ImageField(upload_to='avatars/', blank=True, null=True)
    
    REQUIRED_FIELDS = ['email']
    
    def __str__(self):
        return f"{self.id} user: {self.username} full name: {self.first_name} {self.last_name}"
```

> **Basic Info**
>
> Username, email, first name, and last name

> **Contact**
>
> Optional phone number field (max 10 characters)

> **Avatar**
>
> Profile picture uploaded to 'avatars/' directory

> [!NOTE]
>
> The email field is unique across all users and serves as a primary identifier for authentication.

## Viewing Profile Information

Authenticated users can retrieve their complete profile data.

### API Endpoint

**URL**: `POST /api/users/profile/`

**Authentication**: Required (IsAuthenticated)

**Response**:

```json theme={null}
{
  "id": 1,
  "username": "johndoe",
  "email": "john@example.com",
  "first_name": "John",
  "last_name": "Doe",
  "number_phone": "1234567890",
  "avatar": "/media/avatars/profile_123.jpg"
}
```

### Implementation

The profile view endpoint (`views.py:82-92`):

```python theme={null}
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def profile(request):
    try:
        serializer = UsersSerializer(instance=request.user)
        return Response(serializer.data, status=status.HTTP_200_OK)
    
    except Users.DoesNotExist:
        return Response({'error': 'The user cannot be found in the database.'}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
```

> [!TIP]
>
> The endpoint automatically uses `request.user` to retrieve the authenticated user's profile, ensuring users can only access their own data.

## Updating Profile Information

Users can update their profile details including personal information and avatar.

### API Endpoint

**URL**: `PUT /api/users/update-profile/<pk>/`

**Authentication**: Required (IsAuthenticated)

**Content-Type**: `multipart/form-data` (for avatar uploads)

**Request Body**:

```json theme={null}
{
  "first_name": "Jonathan",
  "last_name": "Doe",
  "number_phone": "0987654321"
}
```

**With Avatar**:

```bash theme={null}
curl -X PUT http://localhost:8000/api/users/update-profile/1/ \
  -H "Authorization: Bearer <token>" \
  -F "first_name=Jonathan" \
  -F "avatar=@profile.jpg"
```

**Response**:

```json theme={null}
{
  "id": 1,
  "username": "johndoe",
  "email": "john@example.com",
  "first_name": "Jonathan",
  "last_name": "Doe",
  "number_phone": "0987654321",
  "avatar": "/media/avatars/profile_123.jpg"
}
```

### Implementation

The update profile endpoint (`views.py:95-117`):

```python theme={null}
@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def update_profile(request, pk):
    try:
        user = get_object_or_404(Users, pk=pk)
        if user != request.user:
            return Response({"error": "Not authorized"}, status=status.HTTP_403_FORBIDDEN)
        
        parser_classes = (MultiPartParser, FormParser)
        
        if 'avatars' in request.FILES:
            avatar = request.FILES['avatar']
            user.avatar = avatar
            user.save()
        
        serializer = UsersSerializer(user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
```

> [!WARNING]
>
> The endpoint includes authorization checks to ensure users can only update their own profiles: `if user != request.user: return Response({"error": "Not authorized"}, ...)`

### Partial Updates

The endpoint supports partial updates (`partial=True`), allowing users to update specific fields without sending the entire profile:

```python theme={null}
serializer = UsersSerializer(user, data=request.data, partial=True)
```

This means you can update just the phone number:

```json theme={null}
{
  "number_phone": "5551234567"
}
```

Or just the avatar:

```bash theme={null}
curl -X PUT http://localhost:8000/api/users/update-profile/1/ \
  -F "avatar=@new_profile.jpg"
```

## Avatar Support

The system supports profile picture uploads with specific handling.

### Avatar Upload Process

**1. File Selection**

User selects an image file through the frontend upload component

**2. Multipart Upload**

File is sent as multipart/form-data in the PUT request

**3. Server Processing**

Backend receives file via `request.FILES['avatar']`

**4. Storage**

Image is saved to `avatars/` directory in media storage

**5. URL Generation**

Django generates a URL path for accessing the uploaded image

### Avatar Upload Component

The frontend includes a dedicated avatar uploader (`AvatarUploader.jsx`):

```jsx theme={null}
export default function AvatarUploader({ currentAvatar, onAvatarChange }) {
  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (file) {
      onAvatarChange(file);
      // Preview the selected image
      const reader = new FileReader();
      reader.onloadend = () => {
        setPreview(reader.result);
      };
      reader.readAsDataURL(file);
    }
  };
  
  return (
    <div>
      <img src={preview || currentAvatar} alt="Profile" />
      <input 
        type="file" 
        accept="image/*" 
        onChange={handleFileChange} 
      />
    </div>
  );
}
```

### Supported Image Formats

The `ImageField` accepts common image formats:

* JPEG (.jpg, .jpeg)
* PNG (.png)
* GIF (.gif)
* WebP (.webp)
* BMP (.bmp)

> [!TIP]
>
> For optimal performance, consider implementing client-side image resizing before upload to reduce bandwidth and storage requirements.

## Account Deletion

Users can permanently delete their accounts and all associated data.

### API Endpoint

**URL**: `DELETE /api/users/delete/<user_id>/`

**Authentication**: Required (IsAuthenticated)

**Response**:

```json theme={null}
{
  "message": "User deleted successfully"
}
```

### Implementation

The delete user endpoint (`views.py:121-129`):

```python theme={null}
@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def delete_user(request, user_id):
    try:
        user = get_object_or_404(Users, id=user_id)
        user.delete()
        return Response({"message": "User deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
```

> [!WARNING]
>
> **Cascade Deletion**: When a user is deleted, all related data is automatically removed due to the `on_delete=models.CASCADE` setting on foreign keys. This includes:
>
> * All saved passwords
> * Uploaded avatar
> * Any other user-related data
>
> This action is **irreversible**.

### Confirmation Flow

Best practice is to implement a confirmation dialog:

```jsx theme={null}
const handleDeleteAccount = async () => {
  const confirmed = window.confirm(
    "Are you sure you want to delete your account? This action cannot be undone."
  );
  
  if (confirmed) {
    try {
      await deleteUser(userId);
      sessionStorage.clear();
      window.location.href = "/auth/sign-up";
    } catch (error) {
      console.error("Error deleting account:", error);
    }
  }
};
```

## Profile Features Summary

> **View Profile**
>
> Retrieve complete profile information including avatar URL

> **Update Info**
>
> Modify personal details with partial update support

> **Upload Avatar**
>
> Upload and update profile pictures with multipart support

> **Delete Account**
>
> Permanently remove account and all associated data

## Frontend Profile Page

The profile page is implemented with a content component (`Content.jsx`) that displays and manages profile information:

```jsx theme={null}
export default function ProfileContent() {
  const [user, setUser] = useState(null);
  const [isEditing, setIsEditing] = useState(false);
  
  useEffect(() => {
    const fetchProfile = async () => {
      const userData = JSON.parse(sessionStorage.getItem('user'));
      setUser(userData);
    };
    fetchProfile();
  }, []);
  
  return (
    <div>
      <AvatarUploader currentAvatar={user?.avatar} />
      <div>
        <p>Username: {user?.username}</p>
        <p>Email: {user?.email}</p>
        <p>Name: {user?.first_name} {user?.last_name}</p>
        <p>Phone: {user?.number_phone}</p>
      </div>
      <button onClick={() => setIsEditing(true)}>Edit Profile</button>
    </div>
  );
}
```

## Authorization Model

Profile management includes multiple layers of authorization:

### Endpoint-Level Authorization

```python theme={null}
@permission_classes([IsAuthenticated])
```

Requires valid JWT token in Authorization header.

### User-Level Authorization

```python theme={null}
if user != request.user:
    return Response({"error": "Not authorized"}, status=status.HTTP_403_FORBIDDEN)
```

Ensures users can only modify their own profiles.

### Automatic User Filtering

```python theme={null}
serializer = UsersSerializer(instance=request.user)
```

Automatically uses the authenticated user from the request.

## Error Handling

| Error Scenario | HTTP Status | Response |
| - | - | - |
| User not found | 404 | `{"error": "The user cannot be found in the database."}` |
| Unauthorized access | 403 | `{"error": "Not authorized"}` |
| Validation error | 400 | `{...serializer.errors}` |
| Server error | 500 | `{"error": "<error message>"}` |

## Media Configuration

For avatar uploads to work properly, ensure your Django settings include:

```python settings.py theme={null}
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
```

And in your URLs configuration:

```python urls.py theme={null}
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... your url patterns
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

> [!NOTE]
>
> In production, serve media files through a CDN or object storage service like AWS S3 rather than directly from Django.

## Best Practices

> **Input Validation**
>
> Validate email format, phone number length, and image file types before submission

> **Image Optimization**
>
> Resize images client-side to reduce upload time and storage costs

> **Error Feedback**
>
> Display clear, actionable error messages for validation failures

> **Confirmation Dialogs**
>
> Require confirmation for destructive actions like account deletion

> [!TIP]
>
> Implement optimistic UI updates for better user experience: update the UI immediately and roll back if the API call fails.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.